<?php
/**
 * @package Joomla
 * @subpackage Jmonoslideshow
 * @copyright (C) 2010 - Matthieu BARBE - www.ccomca.com
 * @license GNU/GPL v2
 * 
 * Jmonoslideshow is a Joomla extension for Monoslideshow.
 *
 * Jmonoslideshow uses :
 * Monoslideshow (http://www.monoslideshow.com/)
 * Plupload (http://www.plupload.com/) by Moxicode Systems
 * json class by Michal Migurski, Matt Knapp, Brett Stimmerman
 * jquery a JavaScript Library (http://jquery.com/)
 * getid3 library (http://getid3.sourceforge.net/)
 * swfobject is an easy-to-use and standards-friendly method to embed Flash content, which utilizes one small JavaScript file (http://code.google.com/p/swfobject/)
 * Chained Selects jQuery Plugin (http://www.appelsiini.net/2010/jquery-chained-selects)
 *
 * Jmonoslideshow is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );

jimport('joomla.application.component.controller');
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.folder');
class JmonoslideshowControllerUpload extends JController
{
	/**
	 * Custom Constructor
	 */
	function __construct( $default = array() )
	{
		$document = & JFactory::getDocument();
		$doc = &JDocument::getInstance('raw');
		$document = $doc;
		$document->setMimeEncoding('application/json') ;
		parent::__construct( $default );
	}
	
	/**
	* Upload media
	*
	* @since 2.0
	*
	*/
	
	function uploadMedia()
    {
		$file 		= JRequest::getVar( 'file', '', 'files', 'array' );
		$chunk		= JRequest::getVar( 'chunk', null, 'post', 'int' );
		$chunks		= JRequest::getVar( 'chunks', null, 'post', 'int' );
		$name		= JRequest::getVar( 'name' );
		$err		= null;
		$params = &JComponentHelper::getParams( 'com_jmonoslideshow' );
		$response['html'] = '';
			//secure check
		if (JRequest::getVar( 'check', null, 'post' )!=JUtility::getToken()) {
			$response['html'] = 'error';
			$response['msg'] = JText::_('COM_JMONOSLIDESHOW_SECURE_CHECK');
			$err = JText::_('COM_JMONOSLIDESHOW_SECURE_CHECK');
			}
		
		$allowed_mime = "image/jpeg,image/gif,image/png,application/x-shockwave-flash";
		$validFileExts = MediaHelper::extension_authorize();
		$extension = strtolower(JFile::getExt($file['name']));
		if (is_null( $err )) $check = $this->check($file, $err, $validFileExts, $allowed_mime, $params);
		if ($check) $chunk = $this->chunk($file, $err, $chunk, $chunks, $name);
		
		if ($check)
			{
				$response['html'] = 'success';
				$response['msg'] = JText::_('COM_JMONOSLIDESHOW_MEDIA_IS_UPLOADED');
				$response['fileName'] = $file['name'];
				$response['type'] = MediaHelper::getType($extension);
				$response['extension'] = MediaHelper::getExtension($extension);
			}
			else
			{	
				$response['html'] = 'error';
				$response['msg'] = $err;
			}
		
		
		$this->_output($response);
	}
	
	
	/**
	* Upload image for album
	*
	* @since 2.0
	*
	*/
	
	function uploadThumb()
    {
		$file 		= JRequest::getVar( 'file', '', 'files', 'array' );
		$chunk		= JRequest::getVar( 'chunk', null, 'post', 'int' );
		$chunks		= JRequest::getVar( 'chunks', null, 'post', 'int' );
		$name		= JRequest::getVar( 'name' );
		$err		= null;
		$params = &JComponentHelper::getParams( 'com_jmonoslideshow' );
		$response['html'] = '';
			//secure check
		if (JRequest::getVar( 'check', null, 'post' )!=JUtility::getToken()) {
			$response['html'] = 'error';
			$response['msg'] = JText::_('COM_JMONOSLIDESHOW_SECURE_CHECK');
			$err = JText::_('COM_JMONOSLIDESHOW_SECURE_CHECK');
			}
		
		$allowed_mime = "image/jpeg,image/gif,image/png";
		$validFileExts = "jpg,png,jpeg,gif";
		$extension = strtolower(JFile::getExt($file['name']));
		if (is_null( $err )) $check = $this->check($file, $err, $validFileExts, $allowed_mime, $params);
		if ($check) $chunk = $this->chunk($file, $err, $chunk, $chunks, $name);
		
		if ($check)
			{
				$response['html'] = 'success';
				$response['msg'] = JText::_('COM_JMONOSLIDESHOW_MEDIA_IS_UPLOADED');
				$response['fileName'] = $file['name'];
			}
			else
			{	
				$response['html'] = 'error';
				$response['msg'] = $err;
			}
		
		
		$this->_output($response);
	}
    
    
	/**
	* Check an upload file
	*
	* @since 2.0
	*
	* @param string $file 
	* @param string $err
	* @param string $validFileExts
	* @param string $allowed_mime
	* @param array $params
	*
	* @return true or false
	*/
	
	function check($file, &$err, $validFileExts, $allowed_mime, $params)
    {
    	if (!$params) {
			$params = &JComponentHelper::getParams( 'com_jmonoslideshow' );
		}

		if(empty($file['name'])) {
			$err = JText::_('COM_JMONOSLIDESHOW_PLEASE_INPUT_A_FILE');
			return false;
		}

		
		/*if ($file['name'] !== JFile::makesafe($file['name'])) {
			$err = JText::_('WARNFILENAME'); 
			return false;
		}*/
		
		//any errors the server registered on uploading
	$fileError = $file['error'];
	if ($fileError > 0)
	{
		switch ($fileError)
			{
			case 1:
			$err = JText::_('COM_JMONOSLIDESHOW_FILE_TO_LARGE_THAN_PHP_INI_ALLOWS');
			return false;
			
			case 2:
			$err = JText::_('COM_JMONOSLIDESHOW_FILE_TO_LARGE_THAN_HTML_FORM_ALLOWS');
			return false;
			
			case 3:
			$err = JText::_('COM_JMONOSLIDESHOW_ERROR_PARTIAL_UPLOAD');
			return false;
			}
	}

		
		
		//check the file extension is ok
		$format = strtolower(JFile::getExt($file['name']));
		
		$validFileExts = explode(",", $validFileExts);
		
		//assume the extension is false until we know its ok
		$extOk = false;
		
		//go through every ok extension, if the ok extension matches the file extension (case insensitive)
		//then the file extension is ok
		foreach($validFileExts as $key => $value)
			{
				if( preg_match("/$value/i", $format ) )
				{
					$extOk = true;
					
				}
			}
			
			if ($extOk == false)
			{
				$err = JText::_('COM_JMONOSLIDESHOW_INVALID_EXTENSION');
				return false;
			
			}

		//check for filesize
		$fileSize = (int) $file['size'];
		if($fileSize > (1048576*$params->get( 'upload_maxsize', 4)) )
			{
				$err = JText::_('COM_JMONOSLIDESHOW_FILE_BIGGER');
				return false;
			}
		$imginfo = null;

		$images = explode( ',', '.jpg,.png,.jpeg,.gif');
		
			
		if(in_array($format, $images)) { // if its an image run it through getimagesize
			if(($imginfo = getimagesize($file['tmp_name'])) === FALSE) {
					$err = JText::_('COM_JMONOSLIDESHOW_INVALID_IMAGE');
					return false;
			}
		}
			

		// if its not an image...and we're not ignoring it
		$allowed_mime = explode(',', $allowed_mime);

		if(function_exists('finfo_open') && $params->get('check_mime',1)) {
			// We have fileinfo
			$finfo = finfo_open(FILEINFO_MIME);
			$type = finfo_file($finfo, $file['tmp_name']);
				if(strlen($type) && !in_array($type, $allowed_mime)) {
						$err = JText::_('COM_JMONOSLIDESHOW_INVALID_MIME');
						return false;
				}
				finfo_close($finfo);

				} else if(function_exists('mime_content_type') && $params->get('check_mime',1)) {

					// we have mime magic
					$type = mime_content_type($file['tmp_name']);

					if(strlen($type) && !in_array($type, $allowed_mime)) {
						$err = JText::_('COM_JMONOSLIDESHOW_INVALID_MIME');
						return false;
					}

				}
		
		
		$xss_check =  JFile::read($file['tmp_name'],false,256);
		$html_tags = array('abbr','acronym','address','applet','area','audioscope','base','basefont','bdo','bgsound','big','blackface','blink','blockquote','body','bq','br','button','caption','center','cite','code','col','colgroup','comment','custom','dd','del','dfn','dir','div','dl','dt','em','embed','fieldset','fn','font','form','frame','frameset','h1','h2','h3','h4','h5','h6','head','hr','html','iframe','ilayer','img','input','ins','isindex','keygen','kbd','label','layer','legend','li','limittext','link','listing','map','marquee','menu','meta','multicol','nobr','noembed','noframes','noscript','nosmartquotes','object','ol','optgroup','option','param','plaintext','pre','rt','ruby','s','samp','script','select','server','shadow','sidebar','small','spacer','span','strike','strong','style','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','ul','var','wbr','xml','xmp','!DOCTYPE', '!--');
		foreach($html_tags as $tag) {
			// A tag is '<tagname ', so we need to add < and a space or '<tagname>'
			if(stristr($xss_check, '<'.$tag.' ') || stristr($xss_check, '<'.$tag.'>')) {
				$err = JText::_('COM_JMONOSLIDESHOW_WARNING_XSS');
				return false;
			}
		}

		return true;
    }
	
	
	/**
	* chunk an upload file
	*
	* @since 2.0
	*
	* @param string $file 
	* @param string $err
	* @param int $chunk
	* @param int $chunks
	* @param string $chunks
	*
	* @return
	*/
	
	function chunk ($file, &$err, $chunk, $chunks, $name)
	{
	
	$chunk = isset($chunk) ? $chunk : 0;
	$chunks = isset($chunks) ? $chunks : 0;
	//$targetDir = JPATH_SITE.DS.'images'.DS.'monoslideshow'.DS.'tmp'.DS;
	$targetDir = JPATH_CACHE.DS;

	if (!file_exists($targetDir))
	@mkdir($targetDir);
	
	$fileName = JFile::makeSafe($file['name']);
	$fileNameTemp = isset($name) ? $name : '';
	if ($chunks < 2 && file_exists($targetDir . DS .$fileNameTemp)) {
		$ext = strrpos($fileNameTemp, '.');
		$fileName_a = substr($fileNameTemp, 0, $ext);
		$fileName_b = substr($fileNameTemp, $ext);

		$count = 1;
		while (file_exists($targetDir . DS .$fileName_a . '_' . $count . $fileName_b))
			$count++;

		$fileNameTemp = $fileName_a . '_' . $count . $fileName_b;
	}
	
		if (isset($file['tmp_name']) && is_uploaded_file($file['tmp_name'])) {
			// Open temp file
			$out = fopen($targetDir . DS .$fileNameTemp, $chunk == 0 ? "wb" : "ab");
			if ($out) {
				// Read binary input stream and append it to temp file
				$in = fopen($file['tmp_name'], "rb");

				if ($in) {
					while ($buff = fread($in, 4096))
						fwrite($out, $buff);
				}
				
				fclose($out);
				@unlink($file['tmp_name']);
			}
}
	}
    
    
    /**
	* output response
	*
	* @since 2.0
	*
	* @param array $response 
	*
	* @return json response
	*/
	
	function _output($response)
    {
    	
		if( function_exists('json_encode') )
		{
			echo ( json_encode( $response ) );
		}
	else
		{
			//--seems we are in PHP < 5.2... or json_encode() is disabled
			require JPATH_COMPONENT_ADMINISTRATOR . DS. 'library' . DS .'json.php' ;
			$json = new Services_JSON();
			echo $json->encode( $response );
		}
		
    }
    
	
	
}
